<html>
<head><meta charset="utf-8"><title>pyo3 (python / c) ffi unwind · project-ffi-unwind · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/index.html">project-ffi-unwind</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/pyo3.20(python.20.2F.20c).20ffi.20unwind.html">pyo3 (python / c) ffi unwind</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="193380026"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/pyo3%20%28python%20/%20c%29%20ffi%20unwind/near/193380026" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> David Hewitt <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/pyo3.20(python.20.2F.20c).20ffi.20unwind.html#193380026">(Apr 08 2020 at 21:20)</a>:</h4>
<p>Hello, I've been recently looking into panic behavior in pyo3, with a draft PR (<a href="https://github.com/PyO3/pyo3/pull/797" title="https://github.com/PyO3/pyo3/pull/797">https://github.com/PyO3/pyo3/pull/797</a>) using <code>catch_unwind</code> to guard against current UB (as I understand it) of unwinding through CPython stack frames. (For Rust functions called by the Python interpreter.)</p>
<p>If I'm reading the ffi-unwind group materials correctly, it sounds like the "C unwind" ABI would also make panics well-defined without needing to introduce <code>catch_unwind</code>. Is that correct?</p>
<p>If you're interested in any details of pyo3 that would be helpful / relevant to this group's work, I'd be happy to offer them. Thanks.</p>



<a name="193380364"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/pyo3%20%28python%20/%20c%29%20ffi%20unwind/near/193380364" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Amanieu <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/pyo3.20(python.20.2F.20c).20ffi.20unwind.html#193380364">(Apr 08 2020 at 21:23)</a>:</h4>
<p>Note that the FFI code you are unwinding into also needs to support unwinding by performing the proper cleanups on unwind. So this only really works for C++ code, not C.</p>



<a name="193381468"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/pyo3%20%28python%20/%20c%29%20ffi%20unwind/near/193381468" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> BatmanAoD (Kyle Strand) <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/pyo3.20(python.20.2F.20c).20ffi.20unwind.html#193381468">(Apr 08 2020 at 21:35)</a>:</h4>
<p>...unless your C code doesn't need any sort of "cleanup"; I think it's correct to think of it as being semantically identical to <code>longjmp</code> over the unwound frames.</p>



<a name="193381562"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/pyo3%20%28python%20/%20c%29%20ffi%20unwind/near/193381562" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Amanieu <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/pyo3.20(python.20.2F.20c).20ffi.20unwind.html#193381562">(Apr 08 2020 at 21:36)</a>:</h4>
<p>Your C code does need to be compiled with <code>-fexceptions</code> though.</p>



<a name="193381582"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/pyo3%20%28python%20/%20c%29%20ffi%20unwind/near/193381582" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> BatmanAoD (Kyle Strand) <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/pyo3.20(python.20.2F.20c).20ffi.20unwind.html#193381582">(Apr 08 2020 at 21:36)</a>:</h4>
<p>Right.</p>



<a name="193381654"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/pyo3%20%28python%20/%20c%29%20ffi%20unwind/near/193381654" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> BatmanAoD (Kyle Strand) <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/pyo3.20(python.20.2F.20c).20ffi.20unwind.html#193381654">(Apr 08 2020 at 21:37)</a>:</h4>
<p>But in the pyo3 case, the cpython frames are the Python interpreter itself, right? It seems unlikely that any Python user would want that.</p>



<a name="193381696"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/pyo3%20%28python%20/%20c%29%20ffi%20unwind/near/193381696" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> BatmanAoD (Kyle Strand) <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/pyo3.20(python.20.2F.20c).20ffi.20unwind.html#193381696">(Apr 08 2020 at 21:37)</a>:</h4>
<p>...and of course it's unlikely that the Python interpreter's stack frames are "clean-up free".</p>



<a name="193381786"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/pyo3%20%28python%20/%20c%29%20ffi%20unwind/near/193381786" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> BatmanAoD (Kyle Strand) <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/pyo3.20(python.20.2F.20c).20ffi.20unwind.html#193381786">(Apr 08 2020 at 21:38)</a>:</h4>
<p>So <code>catch_unwind</code> seems very preferable.</p>



<a name="193382371"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/pyo3%20%28python%20/%20c%29%20ffi%20unwind/near/193382371" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> David Hewitt <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/pyo3.20(python.20.2F.20c).20ffi.20unwind.html#193382371">(Apr 08 2020 at 21:44)</a>:</h4>
<p>Great, that makes sense, thanks. The model we're heading toward is to use <code>catch_unwind</code> convert a Rust panic into a Python exception at the language boundary, and let the interpreter bubble it up through the "Python" stack frames.</p>



<a name="193382521"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/pyo3%20%28python%20/%20c%29%20ffi%20unwind/near/193382521" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> David Hewitt <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/pyo3.20(python.20.2F.20c).20ffi.20unwind.html#193382521">(Apr 08 2020 at 21:46)</a>:</h4>
<p>It then seems reasonable that if that Python exception gets returned to Rust code in some higher stack frame we should then restart Rust's unwinding with <code>resume_unwind</code>.</p>



<a name="193382656"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/pyo3%20%28python%20/%20c%29%20ffi%20unwind/near/193382656" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> David Hewitt <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/pyo3.20(python.20.2F.20c).20ffi.20unwind.html#193382656">(Apr 08 2020 at 21:48)</a>:</h4>
<p>If we did this <code>catch / resume</code> unwind dance, would "C unwind" simply offer no benefit here then? Or would it actually be actively harmful if the Python interpreter is not compiled with <code>-fexceptions</code></p>



<a name="193382910"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/pyo3%20%28python%20/%20c%29%20ffi%20unwind/near/193382910" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Amanieu <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/pyo3.20(python.20.2F.20c).20ffi.20unwind.html#193382910">(Apr 08 2020 at 21:50)</a>:</h4>
<p>"C unwind" is probably not useful for your case. You want to turn a Rust panic into a Python exception, but "C unwind" turns a Rust panic into a C++ exception.</p>



<a name="193383363"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/pyo3%20%28python%20/%20c%29%20ffi%20unwind/near/193383363" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> David Hewitt <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/pyo3.20(python.20.2F.20c).20ffi.20unwind.html#193383363">(Apr 08 2020 at 21:55)</a>:</h4>
<p>Ok great. Thanks! <span aria-label="thumbs up" class="emoji emoji-1f44d" role="img" title="thumbs up">:thumbs_up:</span></p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>